#include <GL/glut.h>

void handleKeypress( unsigned char key, int x, int y );

void timerFunction( int value ) 
{
	// Moving Snanke
	snakeObj.moveSnake( appleObj.giveApple() );
	
	// Adding snake object to the screen
	dispObj.addElementToScreen( snakeObj.giveSnake(), snakeObj.firstPrevState, snakeObj.lastPrevState );
	
	// Redisplaying the window
	glutPostRedisplay();
	

	// Set timer.  Calls update in 1000 msec = 1 sec
	glutTimerFunc( 500, timerFunction, 0 );
}

// Output to screen
void drawScene() 
{
	// Clears the screen to the COLOR_BUFFER which is black
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
	
	// Switch to the drawing perspective
	glMatrixMode( GL_MODELVIEW ); 
	
	// Reset the drawing perspective
	glLoadIdentity(); 
	
	// Place cube three units aways from user
	glTranslatef( 0.0f, 0.0f, -3.0f ); 
	
	// Angle values are changed by user input
	glRotatef( _yAngle, 0.0f, 1.0f, 0.0f ); //Rotate about the z-axis
	glRotatef( _xAngle, 1.0f, 0.0f, 0.0f ); // Rotate Camera on x-axis
	
	// Start creating OpenGl Graphics
	//   Will make Quadratic figures
	glBegin( GL_QUADS );
    
		// Creating RED forward facing shape
		glColor3f( 0.5, 0.2, 0.2 );
		glNormal3f(0.0f, 0.0f, 1.0f);
		glVertex3f( (float)0/10 - 0.75f, (float)-1/10 - 0.75f, (float)15/10 - 0.75f );
		glVertex3f( (float)15/10 - 0.75f, (float)-1/10 - 0.75f, (float)15/10 - 0.75f );
		glVertex3f( (float)15/10 - 0.75f, (float)-5/10 - 0.75f, (float)15/10 - 0.75f );
		glVertex3f( (float)0/10 - 0.75f, (float)-5/10 - 0.75f, (float)15/10 - 0.75f );
	    
		// Creating YELLOW bottom plane of LED cube.
		glColor3f( 0.2, 0.5, 0.2 );
		glNormal3f(0.0f, 0.0f, 1.0f);
		glVertex3f( (float)0/10 - 0.75f, (float)-1/10 - 0.75f, (float)0/10 - 0.75f );
		glVertex3f( (float)15/10 - 0.75f, (float)-1/10 - 0.75f, (float)0/10 - 0.75f );
		glVertex3f( (float)15/10 - 0.75f, (float)-1/10 - 0.75f, (float)15/10 - 0.75f );
		glVertex3f( (float)0/10 - 0.75f, (float)-1/10 - 0.75f, (float)15/10 - 0.75f );

		/*    
		//Back
		glNormal3f(0.0f, 0.0f, 1.0f);
		glVertex3f( (float)0/10 - 0.75f, (float)-1/10 - 0.75f, (float)z/10 - 0.75f );
		glVertex3f( (float)15/10 - 0.75f, (float)-1/10 - 0.75f, (float)z/10 - 0.75f );
		glVertex3f( (float)0/10 - 0.75f, (float)-5/10 - 0.75f, (float)z/10 - 0.75f );
		glVertex3f( (float)15/10 - 0.75f, (float)-5/10 - 0.75f, (float)z/10 - 0.75f );
	    
		//Left
		glNormal3f(0.0f, 0.0f, 1.0f);
		glVertex3f( (float)0/10 - 0.75f, (float)-1/10 - 0.75f, (float)z/10 - 0.75f );
		glVertex3f( (float)15/10 - 0.75f, (float)-1/10 - 0.75f, (float)z/10 - 0.75f );
		glVertex3f( (float)0/10 - 0.75f, (float)-5/10 - 0.75f, (float)z/10 - 0.75f );
		glVertex3f( (float)15/10 - 0.75f, (float)-5/10 - 0.75f, (float)z/10 - 0.75f );
		*/
	glEnd();

	// Change size of each point
	glPointSize( 5.0f );

	// Begin creating indivual points instead of shapes.
	glBegin( GL_POINTS );		
		
		// Displaying the screen
		dispObj.displayScreen();

		// Creating the GREY LED points
		//glVertex3f( 0, 0, 0 );
		glColor3f( 0.2, 0.2, 0.2 );

		int x, y, z;
		
		for( x = 0 ; x < 16 ; x++ )
		{
			for( y = 0 ; y < 16 ; y++ )
			{
				for( z = 0 ; z < 16 ; z++ )
				{
					if( z == 15 || z == 0 || x == 0 || x == 15 || y == 0 || y == 15 )
					{
						glVertex3f( (float)x/10 - 0.75f, (float)y/10 - 0.75f, (float)z/10 - 0.75f );				
					}
				}
			}
		}

	glEnd();
	
	// No idea...
	glutSwapBuffers();
}

// Called when the window is resized
void handleResize( int w, int h ) 
{
	glViewport( 0, 0, w, h );
	glMatrixMode( GL_PROJECTION );
	glLoadIdentity();
	gluPerspective( 45.0, (double)w / (double)h, 1.0, 200.0 );
}

void initializeGLUT( int argc, char **argv )
{
	//Initialize GLUT
	glutInit( &argc, argv );
	glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
	glutInitWindowSize( 400, 400 );
	
	// Create Window and name it.
	glutCreateWindow( "Senior Project Simulator" );
	glEnable( GL_DEPTH_TEST );
	
	//Set handler functions
	glutDisplayFunc( drawScene );
	glutKeyboardFunc( handleKeypress );
	glutReshapeFunc( handleResize );
	
	// Set timer to call update in 25 msec
	if( TIMER_ON )
	{
		glutTimerFunc( 25, timerFunction, 0 ); 
	}
	
	glutMainLoop();
}